/**
 * 视频号数据拦截详情弹窗组件
 */

import { StyleProvider } from "@ant-design/cssinjs"
import { CheckCircleOutlined, CloseCircleOutlined } from "@ant-design/icons"
import { Button, Checkbox, Modal, Select } from "antd"
import moment from "moment"
import React, { useEffect, useRef, useState } from "react"
import * as xlsx from "xlsx"

import { sendToBackground } from "@plasmohq/messaging"
import { useStorage } from "@plasmohq/storage/hook"

import {
  afterSaleDataMaps,
  ecDataMaps,
  interactDataMaps,
  trafficDataMaps
} from "~/utils/wxDataMaps"
import { ThemeProvider } from "~theme"
import { waitForElements } from "~utils/tools"

// 组件参数
export interface WxCaptureDataDetailModalProps {
  // 注入的shadow dom的id
  HostId: string
  // 状态控制
  visible: boolean
  // 关闭触发器
  onClose: () => void
}

const wxPort = chrome.runtime.connect({ name: "wxHijackDataPort" })

const WxCaptureDataDetailModal: React.FC<WxCaptureDataDetailModalProps> = (
  props
) => {
  // 拦截数据记录时间戳
  const [hijackDataTs] = useStorage("wxHijackDataTs")
  // 拦截数据
  const [hijackData, setHijackData] = useState({})
  // 定时分钟数
  const [timerMinute, setTimerMinute] = useState<number>(5)
  // 记录按钮禁用状态
  const [disRecordBtn, setDisRecordBtn] = useState<boolean>(false)
  // 数据记录状态
  const [recording, setRecording] = useState<boolean>(false)
  // 数据记录提示文字
  const [recordTipTxt, setRecordTipTxt] = useState<string>("数据记录未开始")
  // 数据记录条数
  const [recordCount] = useStorage("wxHijackRecordDataCount")
  // 是否截取流量数据
  const [captureTraffic, setCaptureTraffic] = useState<boolean>(false)
  // 加载loading
  const [loading, setLoading] = useState<boolean>(false)

  // 监听background的产品拦截信息结果
  const waitForProductHijackData = (productNode: HTMLElement) => {
    return new Promise((resolve) => {
      const messageListener = (msg: any) => {
        if (msg.type === "product") {
          clearTimeout(timeout) // 清除超时定时器
          wxPort.onMessage.removeListener(messageListener) // 移除监听器
          resolve(msg.data) // 返回消息
        }
      }

      // 确保监听器在点击之前添加
      wxPort.onMessage.addListener(messageListener)

      // 设置一个超时，防止无限等待
      const timeout = setTimeout(() => {
        wxPort.onMessage.removeListener(messageListener)
        resolve(false)
      }, 3000) // 超时时间设置为 3s

      // 点击商品行
      productNode.click()
    })
  }

  // window hijackEvent响应方法
  const eventFunc = (
    event: CustomEvent<{
      url: string
      response: any
    }>
  ) => {
    // 通知后端处理
    sendToBackground({
      name: "wxHijackAllDataService",
      body: {
        action: "hijack",
        data: event.detail
      }
    }).then()
  }

  // 处理定时记录动作
  const handleIntervalRecord = () => {
    if (!recording) {
      // 正在记录中, 暂停记录
      setRecording(true)
      // 通知后台开始记录数据
      sendToBackground({
        name: "wxHijackAllDataService",
        body: {
          action: "startRecord",
          data: {
            // 定时时间
            intervalMinute: timerMinute
          }
        }
      }).then()
    } else {
      // 开始记录
      setRecording(false)
      // 通知后台停止记录数据
      sendToBackground({
        name: "wxHijackAllDataService",
        body: {
          action: "stopRecord",
          data: {}
        }
      }).then()
    }
  }

  // 挂载事件监听
  useEffect(() => {
    // 初始化cache
    sendToBackground({
      name: "wxHijackAllDataService",
      body: {
        action: "init",
        data: {}
      }
    }).then()
    // 监听hijackEvent事件
    window.addEventListener("hijackEvent", eventFunc)
    return () => {
      // 卸载事件监听
      window.removeEventListener("hijackEvent", eventFunc)
      // 端口关闭
      wxPort.disconnect()
    }
  }, [])

  // 拦截数据记录监听
  // 监听数据变化的时间戳
  useEffect(() => {
    // 获取最新的hijack数据
    sendToBackground({
      name: "wxHijackAllDataService",
      body: {
        action: "getData",
        body: {}
      }
    }).then((res) => {
      setHijackData(res)
      if (!res["isLiving"]) {
        setDisRecordBtn(true)
        if (recordCount > 0) {
          setRecordTipTxt(`已下播，已记录[${recordCount}]条数据`)
        } else {
          setRecordTipTxt("已下播，无法定时记录数据")
        }
        // 如果定时记录中，则停止定时记录
        if (recording) {
          handleIntervalRecord()
        }
      } else {
        setDisRecordBtn(false)
        setRecordTipTxt("数据记录未开始")
      }
    })
  }, [hijackDataTs])

  // 监听流量截取状态
  useEffect(() => {
    if (captureTraffic) {
      // 切换到渠道流量分析
      const element = document.querySelector('[data-text="渠道流量分析"]')
      if (element) {
        ;(element as HTMLElement).click()
      }
    } else {
      // 切换到整体趋势
      const element = document.querySelector('[data-text="整体趋势"]')
      if (element) {
        ;(element as HTMLElement).click()
      }
    }
  }, [captureTraffic])

  // 时间戳日期转换
  const transformTimeStamp = (timestamp: any) => {
    try {
      if (timestamp) {
        return moment.unix(timestamp).format("YYYY-MM-DD HH:mm:ss")
      }
      return ""
    } catch (e) {
      console.log("dg-assistant-error:时间戳日期转换异常", e)
      return ""
    }
  }

  // 导出基础数据的方法
  const exportBaseData = async () => {
    const { data, header } = await sendToBackground({
      name: "wxHijackAllDataService",
      body: {
        action: "export"
      }
    })
    const wb = xlsx.utils.book_new()
    const ws = xlsx.utils.json_to_sheet(data, { header: header })
    xlsx.utils.book_append_sheet(wb, ws, "sheet1")
    xlsx.writeFile(wb, `${data[0]["直播间"]}_${data[0]["开播时间"]}.xlsx`)
  }

  // 导出产品数据的方式
  const exportProductData = async () => {
    setLoading(true)
    // 获取商品标签Tab
    const productTab = Array.from(document.querySelectorAll(".tab-item")).find(
      (element) => element.textContent.trim() === "商品"
    )
    // 获取概览标签Tab
    const overviewTab = Array.from(document.querySelectorAll(".tab-item")).find(
      (element) => element.textContent.trim() === "概览"
    )
    // 每个商品循环获取趋势数据
    // 商品行列表
    let productRows: any[] = []
    if (productTab) {
      // 如果tabItem不包含active-tab的话，点击商品tab
      if (!productTab.classList.contains("active-tab")) {
        ;(productTab as HTMLElement).click()
        // 等待商品列表加载完成
        // 查找商品行元素
        productRows = Array.from(await waitForElements(".ant-table-body tr"))
      } else {
        // 直接获取商品行列表
        productRows = Array.from(
          document.querySelectorAll(".ant-table-body tr")
        )
      }
    }
    // 循环点击商品行，获取商品趋势数据
    while (productRows.length > 0) {
      // 当前商品id
      const curProductId = productRows[0].getAttribute("data-row-key")
      const targetItem = productRows[0] as HTMLElement
      // 点击行
      // targetItem.click()
      // 等待拦截记录返回拦截的商品id
      await waitForProductHijackData(targetItem)
      // 删除对应productRow商品列表中的首个元素, 并更新列表
      productRows.shift()
    }

    // 最后返回到概览标签
    if (overviewTab) {
      // 如果tabItem不包含active-tab的话，点击概览tab
      if (!overviewTab.classList.contains("active-tab")) {
        ;(overviewTab as HTMLElement).click()
      }
    }

    // 获取商品数据
    const { header, data } = await sendToBackground({
      name: "wxHijackAllDataService",
      body: {
        action: "exportProduct",
        data: {}
      }
    })
    // 导出为excel文件
    const wb = xlsx.utils.book_new()
    const ws = xlsx.utils.json_to_sheet(data, { header: header })
    xlsx.utils.book_append_sheet(wb, ws, "sheet1")
    // 图片链接处理
    data.forEach((item, index) => {
      const cellAddress = `A${index + 2}` // A列，从第2行开始
      const cell = ws[cellAddress]

      if (cell && item["商品图片"]) {
        cell.l = { Target: item["商品图片"], Tooltip: "点击查看图片" }
      }
    })
    const fileName = `直播商品数据-${data[0]["店铺名称"]}_${moment().format(
      "YYYY-MM-DD"
    )}.xlsx`
    xlsx.writeFile(wb, fileName)
    setLoading(false)
  }

  // 组件片段
  // 基础信息展示片段
  const infoDataItemFragment = (
    maps: { label: string; key: string }[],
    dataKey: string,
    comKey: string
  ) => {
    return maps.map((item, idx) => {
      const tempInfoData = hijackData[dataKey] || {}
      return (
        <div className={"wx-data-item"} key={comKey + idx}>
          <span>{item.label}</span>
          <span>{tempInfoData[item.key] || 0}</span>
        </div>
      )
    })
  }
  // 额外数据展示片段
  const extraDataItemFragment = () => {
    const extraDataKeys = [
      { label: "内容力", key: "contentPower" },
      { label: "转化力", key: "conversionPower" },
      { label: "渠道流量", key: "channelTraffic" },
      { label: "商品", key: "product" }
    ]
    return extraDataKeys.map((item, idx) => {
      const hasData = hijackData[item.key]
      let exist = Boolean(hasData)
      if (item.key === "channelTraffic") {
        exist = Boolean(hijackData["trafficTrendData"]) && Boolean(hasData)
      }
      return (
        <div className={"wx-data-item"} key={item.key + idx}>
          <span>{item.label}</span>
          <span style={{ fontSize: "12px" }}>
            {exist ? (
              <CheckCircleOutlined style={{ color: "green" }} />
            ) : (
              <CloseCircleOutlined style={{ color: "red" }} />
            )}
          </span>
        </div>
      )
    })
  }
  // 页脚片段
  const modalFooterFragment = () => {
    const timeSelectOptions = [
      { value: 5, label: "5分钟" },
      { value: 10, label: "10分钟" },
      { value: 15, label: "15分钟" }
    ]
    return (
      <div className={"wx-data-footer"}>
        <div className={"wx-data-footer-left"}>
          {recording ? (
            <span>记录中...已记录{recordCount}条数据</span>
          ) : (
            <span>{recordTipTxt}</span>
          )}
        </div>
        <div className={"wx-data-footer-right"}>
          <div>
            <Checkbox
              checked={captureTraffic}
              onChange={(e) => {
                setCaptureTraffic(e.target.checked)
              }}>
              流量数据
            </Checkbox>
          </div>
          <div>
            <span style={{ marginRight: 5 }}>定时记录:</span>
            <Select
              disabled={disRecordBtn}
              value={timerMinute}
              style={{ width: 90 }}
              options={timeSelectOptions}
              getPopupContainer={(trigger) => {
                return trigger.parentNode
              }}
              onChange={(value) => setTimerMinute(value)}
            />
          </div>
          <Button
            key={"data-record"}
            disabled={disRecordBtn}
            onClick={handleIntervalRecord}>
            {recording ? "停止记录" : "开始记录"}
          </Button>
          <Button key={"data-export"} onClick={exportBaseData}>
            数据导出
          </Button>
          <Button
            key={"product-data-export"}
            loading={loading}
            onClick={exportProductData}>
            商品数据导出
          </Button>
        </div>
      </div>
    )
  }

  return (
    <ThemeProvider>
      <StyleProvider
        container={document.getElementById(props.HostId).shadowRoot}>
        <Modal
          key={"wx-capture-data-detail-modal"}
          width={950}
          className={"wx-capture-data-detail-modal-wrapper"}
          open={props.visible}
          footer={false}
          onCancel={props.onClose}
          mask={false}
          title={"视频号数据抓取"}
          getContainer={false}
          maskClosable={false}>
          <div className={"wx-data-wrap"}>
            <div className={"wx-base-info-content"}>
              <div className={"wx-base-info-item"}>
                <span>直播间</span>
                <span>{hijackData["liveRoom"] || ""}</span>
              </div>
              <div className={"wx-base-info-item"}>
                <span>开播时间</span>
                <span>{transformTimeStamp(hijackData["liveStartTime"])}</span>
              </div>
              <div className={"wx-base-info-item"}>
                <span>累计成交金额</span>
                <span>{hijackData["totalGmv"] || ""}</span>
              </div>
              <div className={"wx-base-info-item"}>
                <span>直播中</span>
                <span>{hijackData["isLiving"] ? "是" : "否"}</span>
              </div>
              {!hijackData["isLiving"] ? (
                <div className={"wx-base-info-item"}>
                  <span>下播时间</span>
                  <span>{transformTimeStamp(hijackData["liveEndTime"])}</span>
                </div>
              ) : null}
            </div>
            <div className={"wx-data-title"}>流量指标</div>
            <div className={"wx-data-content"}>
              {infoDataItemFragment(trafficDataMaps, "trafficData", "tfd")}
            </div>
            <div className={"wx-data-title"}>互动指标</div>
            <div className={"wx-data-content"}>
              {infoDataItemFragment(interactDataMaps, "interactData", "itd")}
            </div>
            <div className={"wx-data-title"}>交易指标</div>
            <div className={"wx-data-content"}>
              {infoDataItemFragment(ecDataMaps, "ecData", "ecd")}
            </div>
            <div className={"wx-data-title"}>售后指标</div>
            <div className={"wx-data-content"}>
              {infoDataItemFragment(afterSaleDataMaps, "afterSaleData", "afd")}
            </div>
            <div className={"wx-data-title"}>额外数据</div>
            <div className={"wx-data-content"}>{extraDataItemFragment()}</div>
            {/*页脚组件*/}
            {modalFooterFragment()}
          </div>
        </Modal>
      </StyleProvider>
    </ThemeProvider>
  )
}

export default WxCaptureDataDetailModal
